package org.light.domain;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.light.complexverb.AddUploadDomainField;
import org.light.complexverb.DomainFieldVerb;
import org.light.complexverb.UpdateUploadDomainField;
import org.light.core.PrismInterface;
import org.light.core.PrismInterfaceSerialComparator;
import org.light.core.Verb;
import org.light.easyuilayouts.EasyUIGridPagePI;
import org.light.easyuilayouts.EasyUIMtmPI;
import org.light.easyuilayouts.widgets.Nav;
import org.light.exception.ValidateException;
import org.light.generator.DBDefinitionFactory;
import org.light.generator.DBDefinitionGenerator;
import org.light.generator.NamedUtilMethodGenerator;
import org.light.limitedverb.CountActiveRecords;
import org.light.limitedverb.CountAllRecords;
import org.light.limitedverb.CountSearchByFieldsRecords;
import org.light.limitedverb.DaoOnlyVerb;
import org.light.limitedverb.NoControllerVerb;
import org.light.utils.StringUtil;
import org.light.verb.Activate;
import org.light.verb.ActivateAll;
import org.light.verb.Add;
import org.light.verb.CheckAccess;
import org.light.verb.Clone;
import org.light.verb.CloneAll;
import org.light.verb.Delete;
import org.light.verb.DeleteAll;
import org.light.verb.Export;
import org.light.verb.ExportPDF;
import org.light.verb.ExportPPT;
import org.light.verb.ExportWord;
import org.light.verb.FilterExcel;
import org.light.verb.FilterPDF;
import org.light.verb.FilterPPT;
import org.light.verb.FilterWord;
import org.light.verb.FindById;
import org.light.verb.FindByName;
import org.light.verb.FindFullInfoById;
import org.light.verb.ListActive;
import org.light.verb.ListAll;
import org.light.verb.SearchByFields;
import org.light.verb.SearchByFieldsByPage;
import org.light.verb.SearchIndexedNamesByShortName;
import org.light.verb.SoftDelete;
import org.light.verb.SoftDeleteAll;
import org.light.verb.Toggle;
import org.light.verb.ToggleOne;
import org.light.verb.Update;

public class Prism implements Comparable<Prism>{
	protected long prismId;
	protected String standardName;
	protected long domainClassId;
	protected Domain domain;
	protected long daoimplClassId;
	protected long serviceimplClassId;
	protected long daoId;
	protected Dao dao = new Dao();
	protected DummyDao dummydao;
	protected DaoImpl daoimpl= new DaoImpl();
	protected DummyDaoImpl dummydaoimpl;
	protected long serviceId;
	protected Service service = new Service();
	protected ServiceImpl serviceimpl = new ServiceImpl();
	protected DummyServiceImpl dummyserviceimpl;
	protected String prismComment;
	protected List<Class> classes = new ArrayList<Class>(); 
	protected List<Util> utils = new ArrayList<Util>();
	protected List<Controller> controllers = new ArrayList<Controller>();
	protected String folderPath = "/home/jerry/temp/";
	protected DBDefinitionGenerator dbDefinitionGenerator; 
	protected Set<PrismInterface> pages = new TreeSet<PrismInterface>(new PrismInterfaceSerialComparator());
	protected String packageToken;
	protected TestSuite prismTestSuite;
	protected TestCase daoImplTestCase;
	protected TestCase serviceImplTestCase;
	protected List<Verb> verbs = new ArrayList<Verb>();
	protected List<NoControllerVerb> noControllerVerbs = new ArrayList<NoControllerVerb>();
	protected List<DaoOnlyVerb> daoOnlyVerbs = new ArrayList<DaoOnlyVerb>();
	protected Set<ManyToMany> manyToManies = new TreeSet<ManyToMany>();
	protected Set<Domain> projectDomains = new TreeSet<Domain>();
	protected Boolean withAuth = false;
	protected String title = "";
	protected String subTitle = "";
	protected String footer = "";
	protected String crossOrigin = "";	
	protected String resolution = "low";
	protected Set<DomainFieldVerb> domainFieldVerbs = new TreeSet<>();
	protected Set<Pair> manyToManySlaveNames = new TreeSet<Pair>();
	protected String label;
	protected Nav nav;
	protected String technicalStack = "mjeeeu";
	protected String dbType = "MariaDB";	
	
	public DummyServiceImpl getDummyserviceimpl() {
		return dummyserviceimpl;
	}
	public void setDummyserviceimpl(DummyServiceImpl dummyserviceimpl) {
		this.dummyserviceimpl = dummyserviceimpl;
	}
	public DummyDaoImpl getDummydaoimpl() {
		return dummydaoimpl;
	}
	public void setDummydaoimpl(DummyDaoImpl dummydaoimpl) {
		this.dummydaoimpl = dummydaoimpl;
	}
	
	public Set<DomainFieldVerb> getDomainFieldVerbs() {
		return domainFieldVerbs;
	}
	public void setDomainFieldVerbs(Set<DomainFieldVerb> domainFieldVerbs) {
		this.domainFieldVerbs = domainFieldVerbs;
	}
	public Nav getNav() {
		return nav;
	}
	public void setNav(Nav nav) {
		this.nav = nav;
	}
	public String getTechnicalStack() {
		return technicalStack;
	}
	public void setTechnicalStack(String technicalStack) {
		this.technicalStack = technicalStack;
	}
	public String getDbType() {
		return dbType;
	}
	public void setDbType(String dbType) {
		this.dbType = dbType;
	}
	public Set<Domain> getProjectDomains() {
		return projectDomains;
	}
	public void setProjectDomains(Set<Domain> projectDomains) {
		this.projectDomains = projectDomains;
	}
	public List<Controller> getControllers() {
		return controllers;
	}
	public void setControllers(List<Controller> controllers) {
		this.controllers = controllers;
	}
	
	public List<NoControllerVerb> getNoControllerVerbs() {
		return noControllerVerbs;
	}
	public void setNoControllerVerbs(List<NoControllerVerb> noControllerVerbs) {
		this.noControllerVerbs = noControllerVerbs;
	}
	public List<DaoOnlyVerb> getDaoOnlyVerbs() {
		return daoOnlyVerbs;
	}
	public void setDaoOnlyVerbs(List<DaoOnlyVerb> daoOnlyVerbs) {
		this.daoOnlyVerbs = daoOnlyVerbs;
	}
	
	public List<Util> getUtils() {
		return utils;
	}
	public void setUtils(List<Util> utils) {
		this.utils = utils;
	}
	public void addUtil(Util util){
		this.utils.add(util);
	}
	public long getPrismId() {
		return prismId;
	}
	public List<Class> getClasses() {
		return classes;
	}
	public void setClasses(List<Class> classes) {
		this.classes = classes;
	}
	public void addClass(Class clazz){
		this.classes.add(clazz);
	}
	public void setPrismId(long prismId) {
		this.prismId = prismId;
	}
	public String getStandardName() {
		return standardName;
	}
	public void setStandardName(String standardName) {
		this.standardName = standardName;
	}
	public long getDomainClassId() {
		return domainClassId;
	}
	public void setDomainClassId(long domainClassId) {
		this.domainClassId = domainClassId;
	}
	public Domain getDomain() {
		return domain;
	}
	public void setDomain(Domain domain) {
		this.domain = domain;
	}
	public long getDaoimplClassId() {
		return daoimplClassId;
	}
	public void setDaoimplClassId(long daoimplClassId) {
		this.daoimplClassId = daoimplClassId;
	}
	public DaoImpl getDaoimpl() {
		return this.daoimpl;
	}
	public void setDaoimpl(DaoImpl daoimpl) {
		this.daoimpl = daoimpl;
	}
	public long getServiceImplClassId() {
		return serviceimplClassId;
	}
	public void setServiceImplClassId(long serviceimplClassId) {
		this.serviceimplClassId = serviceimplClassId;
	}
	public ServiceImpl getServiceImpl() {
		return serviceimpl;
	}
	public void setServiceImpl(ServiceImpl serviceimpl) {
		this.serviceimpl = serviceimpl;
	}
	public long getDaoId() {
		return daoId;
	}
	public void setDaoId(long daoId) {
		this.daoId = daoId;
	}
	public Dao getDao() {
		return dao;
	}
	public void setDao(Dao dao) {
		this.dao = dao;
	}
	public long getServiceId() {
		return serviceId;
	}
	public void setServiceId(long serviceId) {
		this.serviceId = serviceId;
	}
	public Service getService() {
		return service;
	}
	public void setService(Service service) {
		this.service = service;
	}
	public String getPrismComment() {
		return prismComment;
	}
	public void setPrismComment(String prismComment) {
		this.prismComment = prismComment;
	}
	
	public void generatePrismFiles(Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException{
		ValidateInfo info = this.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath + "src/" + packagetokenToFolder(this.packageToken);
			writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getDomainSuffix()) + this.getDomain().getCapFirstDomainNameWithSuffix()+ ".java", this.getDomain().generateClassString());
	        
	        if (genDao && this.getDao()!=null){
	        	writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getDaoSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName())+ "Dao.java", this.getDao().generateDaoString());
	        }
	        
	        if (genDaoImpl && this.getDaoImpl() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getDaoimplSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName())+"DaoImpl.java",this.getDaoImpl().generateDaoImplString());
	        }
	        
	        if (genService && this.getService() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName())+"Service.java", this.getService().generateServiceString());
	        }
	        
	        if (genServiceImpl && this.getServiceImpl() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceimplSuffix()) +StringUtil.capFirst(this.getDomain().getStandardName())+"ServiceImpl.java", this.getServiceImpl().generateServiceImplString());
	        }
	        
	        for (Controller controller : this.controllers){
				if (genController && controller.generateControllerString()!= null){
					System.out.println("JerryDebug:Controllers:"+controller.getStandardName());
					writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getControllerSuffix()) + StringUtil.capFirst(controller.getStandardName())
					+".java", controller.generateControllerString());
				}
	        }
	        
	        if (genUi) {
		        for (PrismInterface page : this.pages) {
					page.generatePIFiles(folderPath);
				}

				for (ManyToMany mtm : this.manyToManies) {
					EasyUIMtmPI mPage = mtm.getEuPI();
					mPage.setTechnicalStack(this.domain.getTechnicalStack());
					mPage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					mPage.setNav(this.getNav());
					mPage.getFrame().setNav(this.getNav());
					mPage.generatePIFiles(folderPath);
				}
	        }
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	
	public String getFolderPath() {
		return folderPath;
	}
	public void setFolderPath(String folderPath) {
		this.folderPath = folderPath;
	}
	public DaoImpl getDaoImpl() {
		return daoimpl;
	}
	public void setDaoImpl(DaoImpl daoImpl) {
		this.daoimpl = daoImpl;
	}

	public long getServiceimplClassId() {
		return serviceimplClassId;
	}
	public void setServiceimplClassId(long serviceimplClassId) {
		this.serviceimplClassId = serviceimplClassId;
	}
	public ServiceImpl getServiceimpl() {
		return serviceimpl;
	}
	public void setServiceimpl(ServiceImpl serviceimpl) {
		this.serviceimpl = serviceimpl;
	}

	public DBDefinitionGenerator getDbDefinitionGenerator() {
		return dbDefinitionGenerator;
	}
	public void setDbDefinitionGenerator(DBDefinitionGenerator dbDefinitionGenerator) {
		this.dbDefinitionGenerator = dbDefinitionGenerator;
	}

	public String getPackageToken() {
		return packageToken;
	}
	public void setPackageToken(String packagetoken) {
		if (packagetoken != null){
			this.packageToken = packagetoken;
		}
		for (Util u:this.utils) {
			u.setPackageToken(packagetoken);
		}
	}
	
	public void generatePrismFromDomain(Boolean ignoreWarning) throws Exception{
		if (this.domain != null){
			if (this.getPackageToken() != null){
				this.domain.setPackageToken(packageToken);
			}

			this.domain.decorateCompareTo();
				
			this.dao = new Dao();
			this.dao.setDomain(this.domain);
			this.dao.setPackageToken(this.packageToken);
			this.daoimpl = new DaoImpl();
			this.daoimpl.setPackageToken(this.packageToken);
			this.daoimpl.setDomain(this.domain);
			this.daoimpl.setDao(this.dao);
			
			this.dummydao = new DummyDao();
			this.dummydao.setDomain(this.domain);
			this.dummydao.setPackageToken(this.packageToken);
			
			this.dummydaoimpl = new DummyDaoImpl();
			this.dummydaoimpl.setPackageToken(this.domain.getPackageToken());
			this.dummydaoimpl.setDomain(this.domain);

			this.service = new Service();
			this.service.setDomain(this.domain);
			this.service.setPackageToken(this.packageToken);
			this.serviceimpl = new ServiceImpl(this.domain);
			this.serviceimpl.setDomain(this.domain);
			this.serviceimpl.setPackageToken(this.packageToken);
			this.serviceimpl.setService(this.service);
			this.dummyserviceimpl = new DummyServiceImpl(this.domain);
			this.dummyserviceimpl.setDomain(this.domain);
			this.dummyserviceimpl.setPackageToken(this.packageToken);
			this.dummyserviceimpl.setService(this.service);
			
			Verb listAll = new ListAll(this.domain);
			Verb update = new Update(this.domain);
			Verb delete = new Delete(this.domain);
			Verb add = new Add(this.domain);
			Verb softdelete = new SoftDelete(this.domain);
			Verb findbyid = new FindById(this.domain);
			Verb findbyname = new FindByName(this.domain);
			Verb listactive = new ListActive(this.domain);
			Verb deleteAll = new DeleteAll(this.domain);
			Verb softDeleteAll = new SoftDeleteAll(this.domain);
			Verb toggle = new Toggle(this.domain);
			Verb toggleOne = new ToggleOne(this.domain);
			Verb searchByFieldsByPage = new SearchByFieldsByPage(this.domain);
			Verb activate = new Activate(this.domain);
			Verb activateAll = new ActivateAll(this.domain);
			Verb export = new Export(this.domain);
			Verb exportPDF = new ExportPDF(this.domain);
			Verb exportWord = new ExportWord(this.domain);
			Verb exportPPT = new ExportPPT(this.domain);
			Verb searchByFields = new SearchByFields(this.domain);
			Verb filterExcel = new FilterExcel(this.domain);
			Verb filterPDF = new FilterPDF(this.domain);
			Verb filterWord = new FilterWord(this.domain);
			Verb filterPPT = new FilterPPT(this.domain);

			Verb clone	= this.domain.hasDomainId() ?new Clone(this.domain):null;
			Verb findFullInfoById = this.domain.hasDomainId() ?new FindFullInfoById(this.domain):null;
			Verb searchIndexedNamesByShortName = this.domain.hasDomainId() ?new SearchIndexedNamesByShortName(this.domain):null;
			Verb cloneAll = this.domain.hasDomainId()  ?new CloneAll(this.domain):null;
			Verb checkAccess = new CheckAccess(this.domain);
			
			CountActiveRecords countActiveRecords = new CountActiveRecords(this.domain);
			CountAllRecords countAllRecords = new CountAllRecords(this.domain);
			CountSearchByFieldsRecords countSearch = new CountSearchByFieldsRecords(this.domain);
			
			for (Field f:this.domain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					domainFieldVerbs.add(new AddUploadDomainField(this.domain,f));
					domainFieldVerbs.add(new UpdateUploadDomainField(this.domain,f));
				}
			}

			this.addVerb(listAll);
			this.addVerb(update);
			this.addVerb(delete);
			this.addVerb(add);
			this.addVerb(softdelete);
			this.addVerb(findbyid);
			this.addVerb(findbyname);
			this.addVerb(listactive);
			this.addVerb(deleteAll);
			this.addVerb(softDeleteAll);
			this.addVerb(toggle);
			this.addVerb(toggleOne);
			this.addVerb(searchByFieldsByPage);
			this.addVerb(activate);
			this.addVerb(activateAll);
			this.addVerb(export);
			this.addVerb(exportPDF);
			this.addVerb(exportWord);
			this.addVerb(exportPPT);
			this.addVerb(searchByFields);
			this.addVerb(filterExcel);
			this.addVerb(filterPDF);
			this.addVerb(filterWord);
			this.addVerb(filterPPT);

			this.addVerb(clone);
			this.addVerb(findFullInfoById);
			this.addVerb(searchIndexedNamesByShortName);
			this.addVerb(cloneAll);
			this.addVerb(checkAccess);

			this.noControllerVerbs.add(countActiveRecords);
			this.noControllerVerbs.add(countAllRecords);
			this.noControllerVerbs.add(countSearch);
			
			for (Verb v: this.verbs){
				v.setDomain(domain);
				Controller controller = new Controller(v,domain);
				controller.setPackageToken(domain.getPackageToken());
				this.controllers.add(controller);
				service.addMethod(v.generateServiceMethodDefinition());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dao.addMethod(v.generateDaoMethodDefinition());
				daoimpl.addMethod(v.generateDaoImplMethod());
				dummyserviceimpl.addMethod(v.generateDummyServiceImplMethod());
				dummydao.addMethod(v.generateDummyDaoMethodDefinition());
				dummydaoimpl.addMethod(v.generateDummyDaoImplMethod());
			}
			
			for (NoControllerVerb nVerb: this.noControllerVerbs){
				nVerb.setDomain(domain);
				service.addMethod(nVerb.generateServiceMethodDefinition());
				serviceimpl.addMethod(nVerb.generateServiceImplMethod());
				dummyserviceimpl.addMethod(nVerb.generateDummyServiceImplMethod());
				dao.addMethod(nVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(nVerb.generateDaoImplMethod());
				dummydao.addMethod(nVerb.generateDummyDaoMethodDefinition());
				dummydaoimpl.addMethod(nVerb.generateDummyDaoImplMethod());			
			}
			
			for (DaoOnlyVerb oVerb: this.daoOnlyVerbs){
				oVerb.setDomain(domain);
				dao.addMethod(oVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(oVerb.generateDaoImplMethod());	
				dummydao.addMethod(oVerb.generateDummyDaoMethodDefinition());
				dummydaoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
			}
			
			DBDefinitionGenerator dbg = DBDefinitionFactory.getInstance("mysql");
			dbg.addDomain(this.domain);
			dbg.setDbName(this.domain.standardName);
			this.setDbDefinitionGenerator(dbg);	

			for (DomainFieldVerb dfv:domainFieldVerbs) {
				DomainFieldController dfc = new DomainFieldController(dfv);
				this.controllers.add(dfc);
			}
			
			if (this.getPages()==null || this.getPages().size()==0){
				EasyUIGridPagePI easyui = new EasyUIGridPagePI(this.domain);
				easyui.setNav(this.getNav());
				easyui.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
				easyui.setDomain(this.domain);
				easyui.getFrame().setNav(this.getNav());
				//easyui.setTechnicalStack(this.technicalStack);
				this.addPage(easyui);
			}
			
			if (this.domain.manyToManies != null && this.domain.manyToManies.size() > 0) {
				for (ManyToMany mtm : this.domain.manyToManies) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.domain.getStandardName();
					if (setContainsDomain(this.projectDomains, masterName)
							&& setContainsDomain(this.projectDomains, slaveName)) {
						Domain tempo = lookupDoaminInSet(this.projectDomains, slaveName);
						Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
						if (myslave == null) continue;
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						ManyToMany mymtm = new ManyToMany(lookupDoaminInSet(this.projectDomains, masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
						mymtm.setValues(mtm.getValues());
						this.manyToManies.add(mymtm);
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.manyToManies) {
				mtm.setTitle(this.title);
				mtm.setSubTitle(this.subTitle);
				mtm.setFooter(this.footer);
				this.service.addMethod(mtm.getAssign().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(mtm.getAssign().generateServiceImplMethod());
				this.dao.addMethod(mtm.getAssign().generateDaoMethodDefinition());
				this.daoimpl.addMethod(mtm.getAssign().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				TwoDomainController tcontroller = new TwoDomainController(mtm.getAssign(),mtm.getMaster(),mtm.getSlave());
				this.controllers.add(tcontroller);

				this.service.addMethod(mtm.getRevoke().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(mtm.getRevoke().generateServiceImplMethod());
				this.dao.addMethod(mtm.getRevoke().generateDaoMethodDefinition());
				this.daoimpl.addMethod(mtm.getRevoke().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getRevoke().generateDummyDaoImplMethod());
				TwoDomainController tcontroller2 = new TwoDomainController(mtm.getRevoke(),mtm.getMaster(),mtm.getSlave());
				this.controllers.add(tcontroller2);

				this.service.addMethod(mtm.getListMyActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(mtm.getListMyActive().generateServiceImplMethod());
				this.dao.addMethod(mtm.getListMyActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(mtm.getListMyActive().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyActive().generateDummyDaoImplMethod());
				TwoDomainController tcontroller3 = new TwoDomainController(mtm.getListMyActive(),mtm.getMaster(),mtm.getSlave());
				this.controllers.add(tcontroller3);

				this.service.addMethod(mtm.getListMyAvailableActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(mtm.getListMyAvailableActive().generateServiceImplMethod());
				this.dao.addMethod(mtm.getListMyAvailableActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(mtm.getListMyAvailableActive().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyAvailableActive().generateDummyDaoImplMethod());
				TwoDomainController tcontroller4 = new TwoDomainController(mtm.getListMyAvailableActive(),mtm.getMaster(),mtm.getSlave());
				this.controllers.add(tcontroller4);
				
				mtm.slave.decorateCompareTo();
				
				Service slaveService = new Service();
				slaveService.setDomain(mtm.slave);
				slaveService.setStandardName(mtm.slave.getCapFirstDomainName() + "Service");
				
				Method slaveServiceSetter = NamedUtilMethodGenerator.generateSetter(mtm.slave.getLowerFirstDomainName()+"Service",
						new Type(mtm.slave.getCapFirstDomainName() + "Service",mtm.getSlave().getPackageToken()+"."+mtm.getSlave().getServiceSuffix()+"."+mtm.getSlave().getCapFirstDomainName() + "Service"));
				this.serviceimpl.addMethod(slaveServiceSetter);
				this.serviceimpl.addClassImports(mtm.slave.getPackageToken()+"."+mtm.getSlave().getServiceimplSuffix()+"."+mtm.slave.getCapFirstDomainName() + "ServiceImpl");
				this.serviceimpl.addOtherService(slaveService);
			}
		}
	}

	public static String packagetokenToFolder(String packageToken){
		String folder = packageToken.replace('.','/');
		folder += "/";
		return folder;
	}
	
	public static String folderToPackageToken(String folder){
		String packagetoken = folder.replace('/', '.');
		if (packagetoken.charAt(packagetoken.length()-1) == '.')
			packagetoken = packagetoken.substring(0, packagetoken.length() -1);
		return packagetoken;
	}

	public TestSuite getPrismTestSuite() {
		return prismTestSuite;
	}
	public void setPrismTestSuite(TestSuite prismTestSuite) {
		this.prismTestSuite = prismTestSuite;
	}
	public TestCase getDaoImplTestCase() {
		return daoImplTestCase;
	}
	public void setDaoImplTestCase(TestCase daoImplTestCase) {
		this.daoImplTestCase = daoImplTestCase;
	}
	public TestCase getServiceImplTestCase() {
		return serviceImplTestCase;
	}
	public void setServiceImplTestCase(TestCase serviceImplTestCase) {
		this.serviceImplTestCase = serviceImplTestCase;
	}
	
	public ValidateInfo validate(Boolean ignoreWarning) {
		List<ValidateInfo> vl = new ArrayList<ValidateInfo>();
		if (this.getDomain() == null) return ValidateInfo.mergeValidateInfo(vl,ignoreWarning);
		ValidateInfo info = this.getDomain().validate();
		vl.add(info);
		return ValidateInfo.mergeValidateInfo(vl,ignoreWarning);
	}
	
	public void expandPackageToken(){
		if (this.packageToken!=null && !"".equals(this.packageToken)){
			if (this.domain != null) this.domain.setPackageToken(this.packageToken);
			if (this.dao != null) this.dao.setPackageToken(this.packageToken);
			if (this.daoimpl != null) this.daoimpl.setPackageToken(this.packageToken);
			if (this.service != null) this.service.setPackageToken(this.packageToken);
			if (this.serviceimpl != null) this.serviceimpl.setPackageToken(this.packageToken);

			for (Class c : this.classes) {
				c.setPackageToken(this.packageToken);
			}
			if (this.prismTestSuite != null) this.prismTestSuite.setPackageToken(this.packageToken);
			if (this.daoImplTestCase != null) this.daoImplTestCase.setPackageToken(this.packageToken);
			if (this.serviceImplTestCase != null) this.serviceImplTestCase.setPackageToken(this.packageToken);
		}
	}
	@Override
	public boolean equals(Object o){
		return (this.compareTo((Prism)o)==0);
	}
	public List<Verb> getVerbs() {
		return verbs;
	}
	public void setVerbs(List<Verb> verbs) {
		this.verbs = verbs;
	}
	public void removeVerb(Verb verb){
		this.verbs.remove(verb);
	}
	
	public void addVerb(Verb verb){
		this.verbs.add(verb);
	}
	
	public void writeToFile(String filePath, String content) throws Exception {
		File f = new File(filePath);
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		f.createNewFile();
		try (Writer fw = new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(f.getAbsolutePath()), "UTF-8"))) {
			fw.write(content, 0, content.length());
		}
	}
	
	protected Boolean setContainsDomain(Set<Domain> set, String domainName) {
		for (Domain d : set) {
			if (d.getStandardName().equals(domainName))
				return true;
		}
		return false;
	}

	protected Domain lookupDoaminInSet(Set<Domain> set, String domainName) {
		for (Domain d : set) {
			if (d.getStandardName().equals(domainName))
				return d;
		}
		return null;
	}

	@Override
	public int compareTo(Prism o) {
		return this.getStandardName().compareTo(o.getStandardName());
	}
	public Boolean getWithAuth() {
		return withAuth;
	}
	public void setWithAuth(Boolean withAuth) {
		this.withAuth = withAuth;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getSubTitle() {
		return subTitle;
	}
	public void setSubTitle(String subTitle) {
		this.subTitle = subTitle;
	}
	public String getFooter() {
		return footer;
	}
	public void setFooter(String footer) {
		this.footer = footer;
	}
	public String getCrossOrigin() {
		return crossOrigin;
	}
	public void setCrossOrigin(String crossOrigin) {
		this.crossOrigin = crossOrigin;
	}
	public String getResolution() {
		return resolution;
	}
	public void setResolution(String resolution) {
		this.resolution = resolution;
	}
	public Set<Pair> getManyToManySlaveNames() {
		return manyToManySlaveNames;
	}
	public void setManyToManySlaveNames(Set<Pair> manyToManySlaveNames) {
		this.manyToManySlaveNames = manyToManySlaveNames;
	}
	public Set<ManyToMany> getManyToManies() {
		return manyToManies;
	}
	public void setManyToManies(Set<ManyToMany> manyToManies) {
		this.manyToManies = manyToManies;
	}
	
	public String getText() {
		if (this.label != null && !this.label.equals(""))
			return this.label;
		else
			return this.standardName;
	}

	public String getLabel() {
		return label;
	}
	public void setLabel(String label) {
		this.label = label;
	}
	public Set<PrismInterface> getPages() {
		return pages;
	}
	public void setPages(Set<PrismInterface> pages) {
		this.pages = pages;
	}
	
	public void addPage(PrismInterface  page) {
		long serial = 0L;
		for (PrismInterface pi:this.pages) {
			if (pi.getSerial()>serial) serial = pi.getSerial();
		}
		serial += 1000L;
		page.setSerial(serial);
		this.pages.add(page);
	}
	
    public void addNoControllerVerb(NoControllerVerb ncVerb) {
		this.noControllerVerbs.add(ncVerb);
    }
    
    public void generateDummyPrismFiles(Boolean ignoreWarning, Boolean genUi, Boolean genController, Boolean genService,
			Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl) throws ValidateException{
		ValidateInfo info = this.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath;
			if (this.packageToken != null && !"".equals(this.packageToken)){
				srcfolderPath = folderPath + "src/" + packagetokenToFolder(this.packageToken);

				writeToFile(srcfolderPath +packagetokenToFolder(this.domain.getDomainSuffix())  +this.getDomain().getCapFirstDomainNameWithSuffix()+ ".java",
					this.getDomain().generateClassString());
			
				if (genDao && this.getDao() != null) {
					writeToFile(
							srcfolderPath + packagetokenToFolder(this.domain.getDaoSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "Dao.java",
							this.getDummydao().generateDaoString());
				}
	
				if (genDaoImpl&&this.getDaoImpl() != null) {
					writeToFile(
							srcfolderPath + packagetokenToFolder(this.domain.getDaoimplSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "DummyDaoImpl.java",
							this.getDummydaoimpl().generateDaoImplString());
				}
	
				if (genService&&this.getService() != null) {
					writeToFile(srcfolderPath +  packagetokenToFolder(this.domain.getServiceSuffix())  + StringUtil.capFirst(this.getDomain().getStandardName())
							+ "Service.java", this.getService().generateServiceString());
				}
	
				if (genServiceImpl&&this.getServiceImpl() != null) {
					writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceimplSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName())
							+ "ServiceImpl.java", this.getDummyserviceimpl().generateServiceImplString());
				}
	
		        for (Controller controller : this.controllers){
					if (genController && controller.generateControllerString()!= null){
						System.out.println("JerryDebug:Controllers:"+controller.getStandardName());
						writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getControllerSuffix()) + StringUtil.capFirst(controller.getStandardName())
						+".java", controller.generateControllerString());
					}
		        }
	
				if (genUi) {
					for (PrismInterface page : this.pages) {
						page.generatePIFiles(folderPath);
					}
	
					for (ManyToMany mtm : this.manyToManies) {
						EasyUIMtmPI mpage = mtm.getEuPI();
						mpage.setTechnicalStack(this.technicalStack);
						mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
						mpage.setNav(this.getNav());
						mpage.generatePIFiles(folderPath);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}
	public DummyDao getDummydao() {
		return dummydao;
	}
	public void setDummydao(DummyDao dummydao) {
		this.dummydao = dummydao;
	}
}
